package org.goldenport.g3.messages.file

import java.io._
import org.goldenport.entity.GEntity
import org.goldenport.entity.content.GContent
import org.goldenport.g3.G3Command
import org.goldenport.g3.messages.Blob

/**
 * @since   Sep. 13, 2010
 * @version Sep. 28, 2010
 * @author  ASAMI, Tomoharu
 */
abstract class FileCommand(aUri: String) extends G3Command(aUri)

/**
 * Creates a file.
 */
abstract class Create(uri: String) extends FileCommand(uri) {
  def openInputStream(): Option[InputStream] = None
}

class EmptyCreate() extends Create("")

class StringCreate(uri: String, val string: String, val encoding:String = "utf-8") extends Create(uri) {
  override def openInputStream(): Option[InputStream] = {
    val bytes = string.getBytes(encoding)
    Some(new ByteArrayInputStream(bytes))
  }
}

class BlobCreate(uri: String, val blob: Blob) extends Create(uri) {
  override def openInputStream(): Option[InputStream] = {
    Some(blob.openInputStream())
  }
}

class GEntityCreate(uri: String, val gentity: GEntity) extends Create(uri) {
  override def openInputStream(): Option[InputStream] = {
    val out = new ByteArrayOutputStream()
    gentity.write(out)
    out.flush()
    Some(new ByteArrayInputStream(out.toByteArray()))
  }
}

class GContentCreate(uri: String, val gcontent: GContent) extends Create(uri) {
  override def openInputStream(): Option[InputStream] = {
    Some(gcontent.openInputStream)
  }
}

/**
 * Reads whole data from the file.
 */
case class Read(aUri: String, val mime: Option[String] = None, val encoding: String = "utf-8") extends FileCommand(aUri)

/**
 * Writes whole data into the file.
 */
abstract class Write(uri: String) extends FileCommand(uri) {
  def openInputStream(): InputStream
}

class StringWrite(uri: String, val text: String, val encoding: String = "utf-8") extends Write(uri) {
  def openInputStream() = {
    new ByteArrayInputStream(text.getBytes(encoding))
  }
}

class BlobWrite(uri: String, val blob: Blob) extends Write(uri) {
  override def openInputStream(): InputStream = {
    blob.openInputStream()
  }
}

class GEntityWrite(uri: String, val gentity: GEntity) extends Write(uri) {
  override def openInputStream(): InputStream = {
    val out = new ByteArrayOutputStream()
    gentity.write(out)
    out.flush()
    new ByteArrayInputStream(out.toByteArray())
  }
}

class GContentWrite(uri: String, val gcontent: GContent) extends Write(uri) {
  override def openInputStream(): InputStream = {
    gcontent.openInputStream
  }
}

/**
 * Removes the file.
 */
case class Remove(aUri: String) extends FileCommand(aUri)

//
object Create {
  def apply() = new EmptyCreate()
  def apply(string: String) = new StringCreate("", string)
  def apply(blob: Blob) = new BlobCreate("", blob)
  def apply(gentity: GEntity) = new GEntityCreate("", gentity)
  def apply(gcontent: GContent) = new GContentCreate("", gcontent)
}

object Write {
  def apply(string: String) = new StringWrite("", string)
  def apply(blob: Blob) = new BlobWrite("", blob)
  def apply(gentity: GEntity) = new GEntityWrite("", gentity)
  def apply(gcontent: GContent) = new GContentWrite("", gcontent)
}
